package medOffice;

import java.sql.Time;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Testes da classe Medico
 * @author Ana Clara
 *
 */
public class MedicoTest {
	
	OutroMedico med1, med2;
	PlanoDeSaude ps1, ps2;
	Map<Integer, List<Time[]>> horariosDisponiveis = new HashMap<Integer, List<Time[]>>();
	
	public class OutroMedico extends Medico {
		
		public OutroMedico(String nome, String cpf) throws Exception {
			super(nome, cpf);
		}
	}

	@Before
	public void setUp() throws Exception {
		med1 = new OutroMedico("Jenesio", "111111111-11");
		med2 = new OutroMedico("Junior", "123456789-01");
		ps1 = new PlanoDeSaude("Unimed", "(83) 2222-2222", 23.0, 20, 1);
		ps2 = new PlanoDeSaude("Cassi", "(83) 2222-2222", 30, 24, 2);
	}
	
	//Testes de inicialização dos Objetos
		
	@Test
	public void listasVaziasTest() {
		Assert.assertNotNull("era pra ter inicializado", med1.getHorariosDisponiveis());
		Assert.assertNotNull("era pra ter inicializado",med2.getHorariosDisponiveis());
		Assert.assertNotNull("era pra ter inicializado",med2.getPlanosDeSaude());
		Assert.assertNotNull("era pra ter inicializado",med1.getPlanosDeSaude());
		Assert.assertTrue("deveria ser vazio", med1.getHorariosDisponiveis().isEmpty());
		Assert.assertTrue("deveria ser vazio", med1.getPlanosDeSaude().isEmpty());
		Assert.assertTrue("deveria ser vazio", med2.getHorariosDisponiveis().isEmpty());
		Assert.assertTrue("deveria ser vazio", med2.getPlanosDeSaude().isEmpty());
	}
	
	// Testes da formatação do tempo consulta e tempo retorno
	
	@Test(expected = Exception.class)
	public void tempoConsultaInvalido() throws Exception{
		med1.setTempoConsulta("2:00:00");
	}
	
	@Test(expected = Exception.class)
	public void tempoConsultaInvalido2() throws Exception{
		med1.setTempoConsulta("2200:00");
	}
	
	@Test(expected = Exception.class)
	public void tempoConsultaInvalido3() throws Exception{
		med1.setTempoConsulta("22;00:00");
	}
	
	@Test(expected = Exception.class)
	public void tempoRetornoInvalido4() throws Exception{
		med1.setTempoRetorno("2:00:000");
	}
	
	@Test(expected = Exception.class)
	public void tempoRetornoInvalido5() throws Exception{
		med1.setTempoRetorno("2a:00:00");
	}
	
	@Test
	public void setTempoConsultaTest(){
		try {
			med1.setTempoConsulta("02:00:00");
			med2.setTempoRetorno("00:40:00");
		} catch (Exception e) {
			Assert.fail("Deveria ter setado os tempos de consulta");
		}
		Assert.assertEquals("Erro no tempo de consulta", med1.getTempoConsulta(), Time.valueOf("02:00:00"));
		Assert.assertEquals("Erro no tempo de retorno", med2.getTempoRetorno(), Time.valueOf("00:40:00"));
	}
	
	// Testes do Plano de Saude
	
	@Test(expected = Exception.class)
	public void planosDeSaudeNull() throws Exception {
		med1.setPlanosDeSaude(null);
	}
	
	@Test(expected = Exception.class)
	public void planosDeSaudeNull2() throws Exception {
		med1.adicionaPlanoDeSaude(ps1);
		med1.adicionaPlanoDeSaude(null);
	}
	
	@Test(expected = Exception.class)
	public void planosDeSaudeRepetidos() throws Exception {
		med1.adicionaPlanoDeSaude(ps1);
		med1.adicionaPlanoDeSaude(ps1);
	}
	
	@Test
	public void adicionaPlanoDeSaudeTest() {
		try {
			med1.adicionaPlanoDeSaude(ps1);
			med2.adicionaPlanoDeSaude(ps1);
			med2.adicionaPlanoDeSaude(ps2);
			Assert.assertEquals("Tamanho devia ser 1", med1.getPlanosDeSaude().size(), 1);
			Assert.assertEquals("Tamanho devia ser 2", med2.getPlanosDeSaude().size(), 2);
		} catch (Exception e) {
			Assert.fail("Nao deveria ter lançado exceção");
		}
	}
	
	@Test
	public void removePlanoDeSaudeNaoAdicionado() throws Exception {
		med1.adicionaPlanoDeSaude(ps1);
		Assert.assertEquals("Tamanho devia ser 1", med1.getPlanosDeSaude().size(), 1);
		Assert.assertNull("Deveria ser null", med1.removePlanoDeSaude(ps2.getCodigo()));
		Assert.assertNotNull("Nao deveria ser null", med1.removePlanoDeSaude(ps1.getCodigo()));
		Assert.assertEquals("Tamanho devia ser 0", med1.getPlanosDeSaude().size(), 0);
	}
	
	// Testes de Horarios
	
	@Test(expected = Exception.class)
	public void setHorarios() throws Exception {
		med1.setHorariosDisponiveis(null);
	}
	
	@Test(expected = Exception.class)
	public void setHorariosComDiaInvalido() throws Exception {
		Map<Integer, List<Time[]>> horariosDisponiveis = new HashMap<Integer, List<Time[]>>();
		List<Time[]> lista = new ArrayList();
		lista.add(new Time[]{ Time.valueOf("02:00:00"), Time.valueOf("02:00:00") });
		horariosDisponiveis.put(8, lista);
		med1.setHorariosDisponiveis(horariosDisponiveis);
	}
	
	@Test(expected = Exception.class)
	public void setHorariosComTamanhoErrado() throws Exception {
		Map<Integer, List<Time[]>> horariosDisponiveis = new HashMap<Integer, List<Time[]>>();
		List<Time[]> lista = new ArrayList();
		lista.add(new Time[]{ Time.valueOf("02:00:00"), Time.valueOf("02:00:00"), Time.valueOf("02:00:00") });
		horariosDisponiveis.put(3, lista);
		med1.setHorariosDisponiveis(horariosDisponiveis);
	}
	
	@Test
	public void setHorariosNoDiaTest() throws Exception {
		List<Time[]> lista = new ArrayList();
		List<Time[]> lista2 = new ArrayList();
		lista.add(new Time[]{ Time.valueOf("02:00:00"), Time.valueOf("04:00:00") });
		horariosDisponiveis.put(2, lista);
		lista2.add(new Time[]{ Time.valueOf("10:00:00"), Time.valueOf("12:00:00") });
		horariosDisponiveis.put(1, lista2);
		horariosDisponiveis.get(1).add(new Time[]{ Time.valueOf("14:00:00"), Time.valueOf("18:00:00") });
		med1.setHorariosDisponiveis(horariosDisponiveis);
		Assert.assertEquals("Deveriam ser iguais", med1.getHorariosDisponiveis(), horariosDisponiveis);
	}
	
	@Test(expected = Exception.class)
	public void chegadaDoDiaInvalido() throws Exception {
		med1.getHorarioChegadaDia(8);
	}
	
	@Test(expected = Exception.class)
	public void saidaDoDiaInvalido() throws Exception {
		med1.getHorarioSaidaDia(8);
	}
	
	@Test
	public void getHorarioChegadaTest() throws Exception {
		setHorariosNoDiaTest();
		Assert.assertEquals("Deveriam ser iguais", med1.getHorariosDisponiveis(), horariosDisponiveis);
		Assert.assertEquals("Horario de chegada errado", med1.getHorarioChegadaDia(2), Time.valueOf("02:00:00"));
		Assert.assertEquals("Horario de chegada errado", med1.getHorarioChegadaDia(1), Time.valueOf("10:00:00"));
	}
	
	@Test(expected = Exception.class)
	public void saidaDoDiaInvalido2() throws Exception {
		setHorariosNoDiaTest();
		med1.getHorarioSaidaDia(3);
	}
	
	@Test
	public void getHorarioSaidaTest() throws Exception {
		setHorariosNoDiaTest();
		Assert.assertEquals("Deveriam ser iguais", med1.getHorariosDisponiveis(), horariosDisponiveis);
		Assert.assertEquals("Horario de saida errado", med1.getHorarioSaidaDia(2), Time.valueOf("04:00:00"));
		Assert.assertEquals("Horario de saida errado", med1.getHorarioSaidaDia(1), Time.valueOf("18:00:00"));
	}
	
	@Test
	public void getHorariosDoDiaTest() throws Exception {
		setHorariosNoDiaTest();
		Assert.assertEquals("Deveriam ser iguais", med1.getHorariosDisponiveis(), horariosDisponiveis);
		Assert.assertEquals("Horarios do dia errado", med1.getHorariosDoDia(2).get(0)[0], Time.valueOf("02:00:00"));
		Assert.assertEquals("Horarios do dia errado", med1.getHorariosDoDia(2).get(0)[1], Time.valueOf("04:00:00"));
		Assert.assertEquals("Horarios do dia errado", med1.getHorariosDoDia(1).size(), 2);
	}
	
	@Test(expected = Exception.class)
	public void adicionaHorarioNodiaTest1() throws Exception {
		med1.adicionaHorarioDisponivel(8,new Time[]{ Time.valueOf("10:00:00"), Time.valueOf("12:00:00") } );
	}
	
	@Test(expected = Exception.class)
	public void adicionaHorarioNodiaTest2() throws Exception {
		med1.adicionaHorarioDisponivel(3,new Time[]{ Time.valueOf("10:00:00"), Time.valueOf("12:00:00"), Time.valueOf("12:00:00") } );
	}
	
	@Test
	public void adicionaHorarioNodiaTest() throws Exception {
		med1.adicionaHorarioDisponivel(3 ,new Time[]{ Time.valueOf("10:00:00"), Time.valueOf("12:00:00") } );
		med1.adicionaHorarioDisponivel(3 ,new Time[]{ Time.valueOf("08:00:00"), Time.valueOf("12:00:00") } );
		Assert.assertEquals("Horarios do dia errado", med1.getHorariosDoDia(3).size(), 2);
		Assert.assertEquals("Horario de chegada errado", med1.getHorarioChegadaDia(3), Time.valueOf("08:00:00"));
	}
	
	@Test(expected = Exception.class)
	public void removeDiaInvalido() throws Exception {
		setHorariosNoDiaTest();
		med1.removeDiaDisponivel(3);
	}
	
	@Test(expected = Exception.class)
	public void removeDiaInvalido2() throws Exception {
		med1.removeDiaDisponivel(0);
	}
	
	@Test
	public void removeDia() throws Exception {
		setHorariosNoDiaTest();
		Assert.assertEquals("Tamanho devia ser 2", 2, med1.getHorariosDisponiveis().size());
		med1.removeDiaDisponivel(1);
		Assert.assertEquals("Tamanho devia ser 1", 1, med1.getHorariosDisponiveis().size());
	}

}
